﻿using System.Collections.Generic;
using System.Linq;
using MIAP.DataAccess.Interfaces;
using MIAP.DataAccess.SqlServer.Model;
using MIAP.Entidades;
using MIAP.Entidades.Enums;

namespace MIAP.DataAccess.Implementaciones.SQL
{
    /// <summary>
    /// Clase de las operaciones de Acceso a Datos para la autenticación al sistema.
    /// </summary>
    public class AutenticacionDao : IAutenticacionDao
    {
        /// <summary>
        /// Comprueba si la credencial de usuario especificada existe.
        /// </summary>
        /// <param name="nombreUsuario">Nombre de usuario de la credencial.</param>
        /// <returns>True si la credencial de usuario existe.</returns>
        public bool ExiststeCredencial(string nombreUsuario)
        {
            bool existe;

            using (var context = new MIAPDBEntities())
            {
                var query = context.usp_ValidaUsuario(nombreUsuario).SingleOrDefault();
                var result = query;
                existe = result.HasValue && result.Value != 0;
            }
            return existe;
        }

        /// <summary>
        /// Obtiene el resumen del usuario asociado a la credencial de usuario especificada.
        /// </summary>
        /// <param name="nombreUsuario">Nombre de usuario de la credencial.</param>
        /// <returns>Una entidad tipo 'UsuarioInfo' conteniendo el resumen del usuario.</returns>
        public UsuarioInfo GetUsuarioCredencial(string nombreUsuario)
        {
            UsuarioInfo result;

            using (var context = new MIAPDBEntities())
            {
                var query = (from usuario in context.usp_ObtenDatosUsuarioSistema(null, null)
                             where usuario.Usuario.ToUpper().Trim() == nombreUsuario.ToUpper().Trim()
                             select new UsuarioInfo
                             {
                                 IdentificadorPortal = usuario.Clave,
                                 IdUsuario = usuario.ID_USUARIO,
                                 NombreUsuario = usuario.Nombre,
                                 AliasUsuario = usuario.Usuario,
                                 ApellidoMaterno = usuario.ApellidoMaterno,
                                 ApellidoPaterno = usuario.ApellidoPaterno,
                                 EstaActivo = usuario.Activo,
                                 Area = usuario.Area,
                                 SubArea = usuario.SubArea
                             }).SingleOrDefault();
                result = query;

            }

            return result;
        }

        /// <summary>
        /// Obtiene el listado de permisos asociados al usuario especificado.
        /// </summary>
        /// <param name="idUsuario">Es el usuario para el cual se buscarán los permisos.</param>
        /// <returns></returns>
        public List<PermisoInfo> GetPermisosUsuario(int idUsuario)
        {
            var result = new List<PermisoInfo>();

            using (var context = new MIAPDBEntities())
            {
                var idPerfil = (from usuario in context.MIAP_USUARIO
                                join perfil in context.MIAP_USUARIO_PERFIL on usuario.ID_USUARIO equals perfil.ID_USUARIO
                                where usuario.ID_USUARIO == idUsuario
                                select perfil.ID_PERFIL).SingleOrDefault();
                
                if (idPerfil != default(int))
                {
                    var query = from perfilPermiso in context.MIAP_PERFIL_URL_PERFIL
                                where perfilPermiso.ID_PERFIL == idPerfil
                                select new PermisoInfo
                                {
                                    Identificador = perfilPermiso.MIAP_PERFIL_URL.ID_PERFIL_URL,
                                    Nombre = perfilPermiso.MIAP_PERFIL_URL.NOMBRE,
                                    Url = perfilPermiso.MIAP_PERFIL_URL.URL
                                };

                    result.AddRange(query.ToList());
                }
            }

            return result;
        }

        /// <summary>
        /// Obtiene el listado de perfiles asociados al usuario especificado.
        /// </summary>
        /// <param name="idUsuario">id del usuario apartir del cual se desea obtener los permisos.</param>
        /// <returns>Una lista deperfiles a los que puede estar asociado el usuario</returns>
        public IList<PerfilInfo> GetPerfiles(int idUsuario)
        {
            IList<PerfilInfo> result;

            using (var context = new MIAPDBEntities())
            {
                //obtenemos los perfiles del usuario
                var idPerfiles = (from usuario in context.MIAP_USUARIO
                                  join perfil in context.MIAP_USUARIO_PERFIL on usuario.ID_USUARIO equals perfil.ID_USUARIO
                                  where usuario.ID_USUARIO == idUsuario
                                  select perfil.ID_PERFIL).ToList();

                // Obtener los perfiles

                var query = from miapPerfil in context.MIAP_PERFIL
                            where idPerfiles.Contains(miapPerfil.ID_PERFIL)
                            select new PerfilInfo
                            {
                                IdPerfil = miapPerfil.ID_PERFIL,
                                EstaActivo = miapPerfil.ACTIVO,
                                Proyecto = new ProyectoInfo
                                    {
                                        IDProyecto = miapPerfil.ID_PROYECTO ?? 0
                                    },
                                Descripcion = miapPerfil.DESCRIPCION,
                                NombrePerfil = miapPerfil.NOMBRE,
                            };
                result = query.ToList();

                // Obtener de cada perfil los permisos correspondientes 
                if (result.Count > 0)
                {
                    foreach (var perfilInfo in result)
                    {
                        perfilInfo.Permisos = (from perfilUrlPerfil in context.MIAP_PERFIL_URL_PERFIL
                                               where perfilUrlPerfil.ID_PERFIL == perfilInfo.IdPerfil
                                               select new PermisoInfo
                                               {
                                                   Identificador = perfilUrlPerfil.MIAP_PERFIL_URL.ID_PERFIL_URL,
                                                   Nombre = perfilUrlPerfil.MIAP_PERFIL_URL.NOMBRE,
                                                   Url = perfilUrlPerfil.MIAP_PERFIL_URL.URL
                                               }).ToList();

                        perfilInfo.Proyecto = perfilInfo.Proyecto.IDProyecto == 0 ? perfilInfo.Proyecto :
                            (from proy in context.MIAP_PROYECTO
                             where proy.ID_PROYECTO == perfilInfo.Proyecto.IDProyecto
                             select new ProyectoInfo
                                 {
                                     IDProyecto = proy.ID_PROYECTO,
                                     NombreProyecto = proy.NOMBRE,
                                     Descripcion = proy.DESCRIPCION,
                                     Estatus = proy.ACTIVO ? "Activo" : "Inactivo",
                                     FechaActualizacion = proy.FECHA_ACTUALIZACION,
                                     FechaCreacion = proy.FECHA_CREACION,
                                     PaqueteCarga = proy.PAQUETE_CARGA,
                                     PeriodoCarga = new PeriodoInfo
                                         {
                                             IdentificadorPeriodo =
                                                proy.MIAP_PERIODO_CARGA.ID_PERIODO_CARGA,
                                             NombrePeriodo = proy.MIAP_PERIODO_CARGA.NOMBRE,
                                             TipoPeriodo = TipoPeriodo.Carga
                                         },
                                     PeriodoInformacion = new PeriodoInfo
                                         {
                                             IdentificadorPeriodo =
                                                 proy.MIAP_PERIODO_INFORMACION.ID_PERIODO_INFORMACION,
                                             NombrePeriodo = proy.MIAP_PERIODO_INFORMACION.NOMBRE,
                                             TipoPeriodo = TipoPeriodo.Carga
                                         }
                                 }).SingleOrDefault();
                    }
                }
            }
            return result;
        }
    }
}
